package cn.madis.ymcc.service.impl;

import cn.madis.ymcc.MediaFeignClient;
import cn.madis.ymcc.SearchFeignClient;
import cn.madis.ymcc.UserFeignClient;
import cn.madis.ymcc.config.Constant;
import cn.madis.ymcc.doc.CourseDoc;
import cn.madis.ymcc.domain.*;
import cn.madis.ymcc.dto.CourseAddDto;
import cn.madis.ymcc.dto.LoginJwtDto;
import cn.madis.ymcc.dto.SmsDto;
import cn.madis.ymcc.mapper.CourseMapper;
import cn.madis.ymcc.result.JSONResult;
import cn.madis.ymcc.service.*;
import cn.madis.ymcc.util.AssertUtil;
import cn.madis.ymcc.utils.LoginSecurityContext;
import cn.madis.ymcc.vo.Course2OrderMax;
import cn.madis.ymcc.vo.Course2OrderMin;
import cn.madis.ymcc.vo.CourseInfoVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Zt
 * @since 2022-08-07
 */
@Service
@Transactional
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private ITeacherService teacherService;
    @Autowired
    private ICourseDetailService courseDetailService;
    @Autowired
    private ICourseMarketService courseMarketService;
    @Autowired
    private ICourseResourceService courseResourceService;
    @Autowired
    private ICourseSummaryService courseSummaryService;
    @Autowired
    private ICourseTeacherService courseTeacherService;
    @Autowired
    private ICourseTypeService courseTypeService;
    @Autowired
    private SearchFeignClient searchFeignClient;
    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Autowired
    private  ICourseChapterService courseChapterService;

    @Autowired
    private MediaFeignClient mediaFeignClient;

    /**
     * 课程添加方法service层
     */
    @Override
    public void save(CourseAddDto courseAddDto) {
        Course course = courseAddDto.getCourse();
        CourseDetail courseDetail = courseAddDto.getCourseDetail();
        CourseMarket courseMarket = courseAddDto.getCourseMarket();
        CourseResource courseResource = courseAddDto.getCourseResource();
        List<Long> teacharIds = courseAddDto.getTeacharIds();
        //1.校验参数
        String name = courseAddDto.getCourse().getName();
        EntityWrapper<Course> wrapper = new EntityWrapper<>();
        wrapper.eq("name",name);
        List<Course> courses = courseMapper.selectList(wrapper);
        boolean b = courses.size() > 0;
        AssertUtil.isFalse(b,"课程已经存在");
        //2.保存课程基本信息表
        Long aLong = addCourse(course, teacharIds);
        //3.保存课程详情表detail
        addDetail(aLong,courseDetail);
        //4.保存课程销售表
        addMarket(aLong,courseMarket);
        //5.保存课程资源表resource
        addResource(aLong,courseResource);
        //6.保存课程统计表summary
        addSummary(aLong);
        //7. 保存teacher和course中间表
        addTeacherCourse(teacharIds,aLong);


    }




    /**
     *保存teacher和course中间表
     */
    private void addTeacherCourse(List<Long> teacharIds, Long aLong) {
        CourseTeacher courseTeacher = new CourseTeacher();
        for (Long teacharId : teacharIds) {
            courseTeacher.setTeacherId(teacharId);
            courseTeacher.setCourseId(aLong);
            courseTeacherService.insert(courseTeacher);
        }

    }

    /**
     *添加Summary表
     */
    private void addSummary(Long aLong) {
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(aLong);
        courseSummaryService.insert(courseSummary);
    }

    /**
     *添加Resource表
     */
    private void addResource(Long aLong,CourseResource courseResource) {
        courseResource.setCourseId(aLong);
        courseResourceService.insert(courseResource);
    }


    /**
     *添加market表
     * 主键强一致
     */
    private void addMarket(Long aLong, CourseMarket courseMarket) {
        courseMarket.setId(aLong);
        courseMarketService.insert(courseMarket);
    }




    /**
     *添加detail表
     * 主键强一致
     */
    private void addDetail(Long aLong, CourseDetail courseDetail) {
        courseDetail.setId(aLong);
        courseDetailService.insert(courseDetail);
    }

    /**
     *添加course表
     */
    private Long addCourse(Course course, List<Long> teacharIds) {
        course.setStatus(Constant.COURSE_STATUS_OFFLINE);
        List<Teacher> teachers = teacherService.selectBatchIds(teacharIds);
        String teacherNames = teachers.stream().map(teacher -> teacher.getName()).collect(Collectors.joining(","));
        course.setTeacherNames(teacherNames);
        //获取上下文获取用户信息
        LoginJwtDto loginJwtDtoContext = LoginSecurityContext.getLoginJwtDtoContext();
        course.setLoginId(loginJwtDtoContext.getId());
        course.setLoginUserName(loginJwtDtoContext.getUsername());
        courseMapper.insert(course);
        return course.getId();
    }


    /**
     * 课程上架
     * @param courseId
     */
    @Override
    public void onLineCourse(Long courseId) {
        //1.参数校验
        AssertUtil.isNotNull(courseId,"课程id不能为空");
        //2.查数据库看状态是否是上架状态
        Course course = courseMapper.selectById(courseId);
        AssertUtil.isFalse(course.getStatus().intValue() == 1,"课程已经上架");//3.将数据库上架状态修改 修改上架时间
        course.setStatus(1);
        updateById(course);
        //4.将数据添加到es中
        CourseDoc courseDoc = new CourseDoc();
        Long id = course.getId();
        BeanUtils.copyProperties(course,courseDoc);
        CourseMarket courseMarket = courseMarketService.selectById(id);
        BeanUtils.copyProperties(courseMarket,courseDoc);
        CourseSummary courseSummary = courseSummaryService.selectById(id);
        BeanUtils.copyProperties(courseSummary,courseDoc);
        Long courseTypeId = course.getCourseTypeId();
        CourseType courseType = courseTypeService.selectById(courseTypeId);
        courseDoc.setChargeName(courseMarket.getCharge().intValue() == 1?"免费":"收费");
        courseDoc.setCourseTypeName(courseType.getName());
        courseDoc.setId(id);
        JSONResult save = searchFeignClient.save(courseDoc);
        AssertUtil.isTrue(save.isSuccess(),"课程发布失败");


        /*//推送信息   短信  邮件  站内信  @TODO
        //短信发送推荐
        JSONResult<List<User>> list = userFeignClient.list();
        List<User> data = list.getData();
        List<MessageSms> list1 = new ArrayList<>();
        SmsDto smsDto = new SmsDto();
        for (User datum : data) {
            MessageSms messageSms = new MessageSms();
            messageSms.setContent(course.getName());
            messageSms.setPhone(datum.getPhone());
            list1.add(messageSms);
        }
        smsDto.setList(list1);
        Message<SmsDto> build = MessageBuilder.withPayload(smsDto).build();
        rocketMQTemplate.asyncSend("topic-user:tags-phone",build, new SendCallback() {
            @Override
            public void onSuccess(SendResult sendResult) {

            }

            @Override
            public void onException(Throwable throwable) {

            }
        });*/


    }

    /**
     * 课程下架
     * @param courseId
     */
    @Override
    public void offLineCourse(Long courseId) {
        //参数校验
        AssertUtil.isNotNull(courseId,"课程id不能为空");
        //修改状态
        //2.查数据库看状态是否是上架状态
        Course course = courseMapper.selectById(courseId);
        AssertUtil.isFalse(course.getStatus().intValue() == 0,"课程已经下架");//3.将数据库上架状态修改 修改上架时间
        course.setStatus(0);
        updateById(course);
        //删除es中数据.
        JSONResult remove = searchFeignClient.remove(courseId);
        AssertUtil.isTrue(remove.isSuccess(),"课程下架失败");


    }


    /**
     * 查询课程详情页数据
     * @param courseId
     * @return
     */
    @Override
    public CourseInfoVo detail(Long courseId) {
        //参数校验
        AssertUtil.isNotNull(courseId,"非法参数");
        //拿到course
        Course course = courseMapper.selectById(courseId);
        //校验course
        AssertUtil.isNotNull(course,"没有课程数据");
        boolean b = course.getStatus().intValue() == 1;
        AssertUtil.isTrue(b,"课程没有上架");

        //查询销售信息
        CourseMarket courseMarket = courseMarketService.selectById(courseId);
        AssertUtil.isNotNull(courseMarket,"课程相关销售信息为空");

        //查询课程详情
        CourseDetail courseDetail = courseDetailService.selectById(courseId);
        AssertUtil.isNotNull(courseDetail,"课程详情为空");

        //查询老师信息
        EntityWrapper<CourseTeacher> wrapper = new EntityWrapper<>();
        wrapper.eq("course_id",courseId);
        List<CourseTeacher> courseTeachers = courseTeacherService.selectList(wrapper);
        List<Long> collect = courseTeachers.stream().map(courseTeacher -> courseTeacher.getTeacherId())
                .collect(Collectors.toList());
        List<Teacher> teachers = teacherService.selectBatchIds(collect);

        //查询课程章节信息

        EntityWrapper<CourseChapter> wrapper1 = new EntityWrapper<>();
        wrapper1.eq("course_id",courseId);
        List<CourseChapter> courseChapters = courseChapterService.selectList(wrapper1);
        //把课程章节转成map让后面视频找章节
        Map<Long, CourseChapter> collect1 = courseChapters.stream()
                .collect(Collectors.toMap(CourseChapter::getId, courseChapter -> courseChapter));

        //用feign调用课程视频表查出章节下视频
        JSONResult media = mediaFeignClient.getMedia(courseId);
        AssertUtil.isTrue(media.isSuccess(),media.getMessage());
        AssertUtil.isNotNull(media.getData(),"课程信息异常，没有视频！！");

        String s = media.getData().toString();
        List<MediaFile> mediaFiles = JSON.parseArray(s, MediaFile.class);
        //视频去找章节
       /* for (MediaFile mediaFile : mediaFiles) {
            collect1.get(mediaFile.getChapterId()).getMediaFiles().add(mediaFile);
        }*/
        mediaFiles.stream().forEach(mediaFile -> {
                 mediaFile.setFileUrl("");
                 collect1.get(mediaFile.getChapterId())
                .getMediaFiles().add(mediaFile);});



        return new CourseInfoVo(course,courseMarket,courseChapters,teachers,courseDetail);
    }

    /**
     * 订单数据查询展示
     * @param courseId
     * @return
     */
    @Override
    public Course2OrderMax info(String courseId) {
        AssertUtil.isNotNull(courseId,"非法参数");
        String[] split = courseId.split(",");
        List<Course> courses = selectBatchIds(Arrays.asList(split));
        Course2OrderMax course2OrderMax = new Course2OrderMax();
        List<Course2OrderMin> courseInfos = new ArrayList<>();
        courses.forEach(course -> {
            boolean b = course.getStatus() == 1;
            AssertUtil.isTrue(b,"课程非法");
            CourseMarket courseMarket = courseMarketService.selectById(course.getId());
            Course2OrderMin course2OrderMin = new Course2OrderMin(course,courseMarket);
            courseInfos.add(course2OrderMin);
            course2OrderMax.setTotalAmount(course2OrderMax.getTotalAmount().add(courseMarket.getPrice()));
        });
        course2OrderMax.setCourseInfos(courseInfos);


        return course2OrderMax;
    }

}
